import React, { useState, useEffect } from 'react';
import { 
  Card, Form, Input, InputNumber, Select, 
  Switch, Button, Table, Spin, Typography, 
  Divider, Space, Row, Col, Collapse, Tag,
  Slider, Progress, Alert, Tooltip, DatePicker,
  Checkbox, message
} from 'antd';
import { 
  ExperimentOutlined, SearchOutlined, ReloadOutlined,
  BarChartOutlined, LineChartOutlined, SaveOutlined,
  TeamOutlined
} from '@ant-design/icons';
import * as echarts from 'echarts';
import moment from 'moment';
import './index.css';
import { fetchStockCodes } from '../../api';
import { optimizationApi } from '../../api';
import { stockGroupApi } from '../../api';

const { Title, Text } = Typography;
const { Option } = Select;
const { Panel } = Collapse;
const { RangePicker } = DatePicker;

// Default parameter ranges
const DEFAULT_PARAM_RANGES = {
  ischeckhs300: [false, true],
  hs300_limit: [10, 50],
  increaseday_range: [10, 40],
  highday_range: [10, 50],
  lowday_range: [5, 30],
  sortType: [1, 2, 3],
  tradeType: [1, 2]
};

// Available cycles for optimization
const AVAILABLE_CYCLES = [
  { value: 'day', label: '日线' },
  { value: '5T', label: '5分钟' },
  { value: '15T', label: '15分钟' },
  { value: '30T', label: '30分钟' },
  { value: '60T', label: '60分钟' }
];

// Component for stock code selection
const StockCodeSelector = ({ selectedCodes, availableCodes, onAddCode, onRemoveCode, onSelectGroup }) => {
  const [stockGroups, setStockGroups] = useState([]);
  const [loading, setLoading] = useState(false);
  const [selectedGroupName, setSelectedGroupName] = useState(null);

  // Find a group that matches the selected codes
  const findMatchingGroup = React.useCallback((groups, codes) => {
    if (!groups || !codes || groups.length === 0 || codes.length === 0) {
      return;
    }
    
    // Sort codes to ensure consistent comparison
    const sortedCodes = [...codes].sort();
    
    // Try to find an exact match
    for (const group of groups) {
      if (group.codes && Array.isArray(group.codes)) {
        const sortedGroupCodes = [...group.codes].sort();
        
        // Check if arrays have the same length and same elements
        if (sortedGroupCodes.length === sortedCodes.length && 
            JSON.stringify(sortedGroupCodes) === JSON.stringify(sortedCodes)) {
          setSelectedGroupName(group.name);
          return;
        }
      }
    }
    
    // If no exact match, clear selection
    setSelectedGroupName(null);
  }, []);

  // Load stock groups
  useEffect(() => {
    const loadStockGroups = async () => {
      try {
        setLoading(true);
        const groups = await stockGroupApi.getAllStockGroups();
        console.log('Loaded stock groups:', groups);
        setStockGroups(Array.isArray(groups) ? groups : []);
        
        // Try to find a matching group based on selected codes
        if (selectedCodes && selectedCodes.length > 0) {
          findMatchingGroup(groups, selectedCodes);
        }
      } catch (error) {
        console.error('Error fetching stock groups:', error);
        message.error('获取股票组合失败');
      } finally {
        setLoading(false);
      }
    };

    loadStockGroups();
  }, [findMatchingGroup, selectedCodes]);
  
  // Check if selected codes match a group when codes change
  useEffect(() => {
    if (stockGroups && stockGroups.length > 0 && selectedCodes && selectedCodes.length > 0) {
      findMatchingGroup(stockGroups, selectedCodes);
    }
  }, [selectedCodes, stockGroups, findMatchingGroup]);

  // Debug when props change
  useEffect(() => {
    console.log('StockCodeSelector - selectedCodes:', selectedCodes);
    console.log('StockCodeSelector - selectedGroupName:', selectedGroupName);
  }, [selectedCodes, selectedGroupName]);

  const handleGroupChange = (groupName) => {
    console.log('Selected group name:', groupName);
    setSelectedGroupName(groupName);
    
    // Find the group by name
    const selectedGroup = stockGroups.find(g => g.name === groupName);
    if (selectedGroup && selectedGroup.codes) {
      // Call the parent's onSelectGroup with the group's codes
      onSelectGroup(selectedGroup.codes);
      message.success(`已加载股票组合: ${selectedGroup.name} (${selectedGroup.codes.length}只股票)`);
    }
  };

  return (
    <div className="stock-code-selector">
      <div className="stock-group-selector" style={{ marginBottom: '10px' }}>
        <Select
          placeholder="选择股票组合"
          style={{ width: '100%' }}
          loading={loading}
          value={selectedGroupName}
          onChange={handleGroupChange}
          allowClear
          optionFilterProp="label"
        >
          {stockGroups.map(group => (
            <Select.Option key={group.name} value={group.name} label={group.name}>
              <Space>
                <TeamOutlined />
                <span>{group.name}</span>
                <span style={{ color: '#888', fontSize: '12px' }}>({group.codes?.length || 0}只股票)</span>
              </Space>
            </Select.Option>
          ))}
        </Select>
      </div>

      <div className="selected-codes">
        {selectedCodes.map(code => (
          <Tag 
            key={code} 
            closable 
            onClose={() => onRemoveCode(code)}
          >
            {code}
          </Tag>
        ))}
      </div>
      
      <Collapse ghost>
        <Panel header="选择股票" key="1">
          <div className="stock-list">
            {availableCodes?.history?.slice(0, 100).map(code => (
              <Button
                key={code}
                size="small"
                type={selectedCodes.includes(code) ? 'primary' : 'default'}
                onClick={() => onAddCode(code)}
                style={{ margin: '4px' }}
              >
                {code}
              </Button>
            ))}
          </div>
        </Panel>
      </Collapse>
    </div>
  );
};

// Component for parameter range input
const ParamRangeInput = ({ label, min, max, defaultMin, defaultMax, onChange, form, paramName }) => {
  // Get current values from form
  const paramRanges = form.getFieldValue('paramRanges') || { ...DEFAULT_PARAM_RANGES };
  const currentValues = paramRanges[paramName] || [defaultMin, defaultMax];
  
  return (
    <div className="param-range-item">
      <span className="param-name">{label}:</span>
      <div className="param-value">
        <div className="range-inputs">
          <InputNumber 
            min={min} 
            max={max}
            value={currentValues[0]}
            style={{ width: '80px' }}
            onChange={(value) => {
              const newValues = [value || defaultMin, currentValues[1]];
              onChange(paramName, newValues);
            }}
          />
          <span className="range-separator">-</span>
          <InputNumber 
            min={min} 
            max={max}
            value={currentValues[1]}
            style={{ width: '80px' }}
            onChange={(value) => {
              const newValues = [currentValues[0], value || defaultMax];
              onChange(paramName, newValues);
            }}
          />
        </div>
        <Slider 
          range 
          min={min} 
          max={max} 
          value={currentValues}
          style={{ width: '100%' }}
          onChange={(values) => {
            onChange(paramName, values);
          }}
        />
      </div>
    </div>
  );
};

// Component for checkbox group parameter
const CheckboxGroupParam = ({ label, options, defaultValue, onChange }) => (
  <div className="param-range-item">
    <span className="param-name">{label}:</span>
    <div className="param-value">
      <Checkbox.Group
        options={options}
        defaultValue={defaultValue}
        onChange={(values) => onChange(values)}
      />
    </div>
  </div>
);

// Component for parameter ranges configuration
const ParamRangesConfig = ({ form }) => {
  const updateParamRange = (paramName, values) => {
    console.log('paramName, values :>> ', paramName, values);
    let ranges = form.getFieldValue('paramRanges') || { ...DEFAULT_PARAM_RANGES };
    
    // Simply update the values for the parameter
    ranges[paramName] = values;
    
    // Update the form
    form.setFieldsValue({ paramRanges: { ...ranges } });
  };

  return (
    <div className="param-ranges">
      <CheckboxGroupParam
        label="考虑沪深300"
        options={[
          { label: '否', value: false },
          { label: '是', value: true }
        ]}
        defaultValue={[false, true]}
        onChange={(values) => updateParamRange('ischeckhs300', values)}
      />
      
      <ParamRangeInput
        label="沪深300限制"
        paramName="hs300_limit"
        min={1}
        max={100}
        defaultMin={10}
        defaultMax={50}
        onChange={updateParamRange}
        form={form}
      />
      
      <ParamRangeInput
        label="涨幅天数范围"
        paramName="increaseday_range"
        min={1}
        max={100}
        defaultMin={10}
        defaultMax={40}
        onChange={updateParamRange}
        form={form}
      />
      
      <ParamRangeInput
        label="高点天数范围"
        paramName="highday_range"
        min={1}
        max={100}
        defaultMin={10}
        defaultMax={50}
        onChange={updateParamRange}
        form={form}
      />
      
      <ParamRangeInput
        label="低点天数范围"
        paramName="lowday_range"
        min={1}
        max={100}
        defaultMin={5}
        defaultMax={30}
        onChange={updateParamRange}
        form={form}
      />
      
      <CheckboxGroupParam
        label="排序类型"
        options={[
          { label: '类型1', value: 1 },
          { label: '类型2', value: 2 },
          { label: '类型3', value: 3 }
        ]}
        defaultValue={[1, 2, 3]}
        onChange={(values) => updateParamRange('sortType', values)}
      />
      
      <CheckboxGroupParam
        label="交易类型"
        options={[
          { label: '类型1', value: 1 },
          { label: '类型2', value: 2 }
        ]}
        defaultValue={[1, 2]}
        onChange={(values) => updateParamRange('tradeType', values)}
      />
    </div>
  );
};

// Component for optimization results table
const ResultsTable = ({ results, optimizationTarget, onSaveResult }) => {
  const resultColumns = [
    {
      title: 'ID',
      dataIndex: ['id'],
      key: 'id',
      width: 60
    },
    {
      title: '参数',
      key: 'parameters',
      render: (_, record) => {
        if (!record || !record.parameters) {
          return <div>无参数数据</div>;
        }
        return (
          <div className="parameter-cell">
            <div><strong>HS300检查:</strong> {record.parameters.ischeckhs300 ? '是' : '否'}</div>
            <div><strong>HS300限制:</strong> {record.parameters.hs300_limit}</div>
            <div><strong>涨幅天数:</strong> {record.parameters.increaseday_range}</div>
            <div><strong>高点天数:</strong> {record.parameters.highday_range}</div>
            <div><strong>低点天数:</strong> {record.parameters.lowday_range}</div>
            <div><strong>排序类型:</strong> {record.parameters.sortType}</div>
            <div><strong>交易类型:</strong> {record.parameters.tradeType}</div>
            {record.parameters.cycle && <div><strong>周期:</strong> {record.parameters.cycle}</div>}
          </div>
        );
      }
    },
    {
      title: '最终收益',
      dataIndex: ['metrics', 'finalReturn'],
      key: 'finalReturn',
      sorter: (a, b) => (a.metrics?.finalReturn || 0) - (b.metrics?.finalReturn || 0),
      render: value => value !== undefined ? `${(value * 100).toFixed(2)}%` : 'N/A',
      width: 100
    },
    {
      title: '年化收益',
      dataIndex: ['metrics', 'annualizedReturn'],
      key: 'annualizedReturn',
      sorter: (a, b) => (a.metrics?.annualizedReturn || 0) - (b.metrics?.annualizedReturn || 0),
      render: value => value !== undefined ? `${(value * 100).toFixed(2)}%` : 'N/A',
      width: 100
    },
    {
      title: '最大回撤',
      dataIndex: ['metrics', 'maxDrawdown'],
      key: 'maxDrawdown',
      sorter: (a, b) => (a.metrics?.maxDrawdown || 0) - (b.metrics?.maxDrawdown || 0),
      render: value => value !== undefined ? `${(value * 100).toFixed(2)}%` : 'N/A',
      width: 100
    },
    {
      title: '夏普比率',
      dataIndex: ['metrics', 'sharpeRatio'],
      key: 'sharpeRatio',
      sorter: (a, b) => (a.metrics?.sharpeRatio || 0) - (b.metrics?.sharpeRatio || 0),
      render: value => value !== undefined ? value.toFixed(2) : 'N/A',
      width: 100
    },
    {
      title: '波动率',
      dataIndex: ['metrics', 'volatility'],
      key: 'volatility',
      sorter: (a, b) => (a.metrics?.volatility || 0) - (b.metrics?.volatility || 0),
      render: value => value !== undefined ? `${(value * 100).toFixed(2)}%` : 'N/A',
      width: 100
    },
    {
      title: '胜率',
      dataIndex: ['metrics', 'winRate'],
      key: 'winRate',
      sorter: (a, b) => (a.metrics?.winRate || 0) - (b.metrics?.winRate || 0),
      render: value => value !== undefined ? `${(value * 100).toFixed(2)}%` : 'N/A',
      width: 100
    },
    {
      title: '操作',
      key: 'action',
      width: 80,
      render: (_, record) => {
        if (!record || !record.parameters) {
          return null;
        }
        return (
          <Button 
            type="primary" 
            size="small" 
            icon={<SaveOutlined />}
            onClick={() => onSaveResult(record)}
          >
            应用
          </Button>
        );
      }
    }
  ];

  const getTargetName = (target) => {
    const targetMap = {
      'finalReturn': '最终收益',
      'annualizedReturn': '年化收益',
      'sharpeRatio': '夏普比率',
      'maxDrawdown': '最小最大回撤',
      'winRate': '胜率'
    };
    return targetMap[target] || target;
  };

  const getCycleName = (cycle) => {
    const cycleMap = AVAILABLE_CYCLES.reduce((acc, c) => {
      acc[c.value] = c.label;
      return acc;
    }, {});
    return cycleMap[cycle] || cycle;
  };

  // Check if results has the expected structure
  if (!results || !results.results || !Array.isArray(results.results)) {
    return (
      <Card 
        title={
          <Space>
            <BarChartOutlined />
            <span>优化结果</span>
          </Space>
        } 
        bordered={false}
      >
        <Alert
          message="数据错误"
          description="无法加载优化结果，请重试。"
          type="error"
          showIcon
        />
      </Card>
    );
  }

  return (
    <Card 
      title={
        <Space>
          <BarChartOutlined />
          <span>优化结果</span>
        </Space>
      } 
      bordered={false}
    >
      <div className="results-summary">
        <Alert
          message="优化完成"
          description={
            <div>
              <p>共测试了 {results.iterations || 0} 种参数组合，下面显示按 {getTargetName(optimizationTarget)} 排序的前 {results.results.length} 个结果。</p>
              {results.cycle && <p>回测周期: {getCycleName(results.cycle)}</p>}
              {results.dateRange && <p>回测日期: {results.dateRange.startDate} 至 {results.dateRange.endDate}</p>}
            </div>
          }
          type="success"
          showIcon
        />
      </div>
      
      <Table
        dataSource={results.results}
        columns={resultColumns}
        pagination={{ pageSize: 10 }}
        rowKey="id"
        size="middle"
        scroll={{ x: 'max-content' }}
      />
    </Card>
  );
};

// Main Optimization component
const Optimization = () => {
  const [form] = Form.useForm();
  const [loading, setLoading] = useState(false);
  const [optimizing, setOptimizing] = useState(false);
  const [progress, setProgress] = useState(0);
  const [results, setResults] = useState(null);
  const [availableCodes, setAvailableCodes] = useState({
    history: [],
    real: []
  });
  const [selectedCodes, setSelectedCodes] = useState([
    "000016.XSHG", "000852.XSHG", "399673.XSHE", "513100.XSHG", "518880.XSHG"
  ]);
  
  // Load stock codes on component mount
  useEffect(() => {
    const loadStockCodes = async () => {
      try {
        const data = await fetchStockCodes();
        setAvailableCodes(data);
      } catch (error) {
        console.error('Error fetching stock codes:', error);
      }
    };
    
    loadStockCodes();
    
    // Set form initial values
    form.setFieldsValue({
      codes: ["000016.XSHG", "000852.XSHG", "399673.XSHE", "513100.XSHG", "518880.XSHG"],
      paramRanges: DEFAULT_PARAM_RANGES,
      optimizationTarget: 'sharpeRatio',
      iterationCount: 100,
      dateRange: null,
      cycle: 'day' // Default to daily cycle
    });
  }, [form]);
  
  const handleAddCode = (code) => {
    if (!selectedCodes.includes(code)) {
      const newCodes = [...selectedCodes, code];
      setSelectedCodes(newCodes);
      form.setFieldsValue({ codes: newCodes });
    }
  };

  const handleRemoveCode = (code) => {
    const newCodes = selectedCodes.filter(c => c !== code);
    setSelectedCodes(newCodes);
    form.setFieldsValue({ codes: newCodes });
  };
  
  // Handle stock group selection
  const handleSelectGroup = async (groupCodes) => {
    if (!groupCodes || !Array.isArray(groupCodes) || groupCodes.length === 0) {
      // If no codes provided, keep the current selection
      return;
    }
    
    console.log('Setting stock codes from group:', groupCodes);
    
    // Just set the codes directly since we're now receiving the codes array
    setSelectedCodes(groupCodes);
    form.setFieldsValue({ codes: groupCodes });
  };
  
  // Start optimization process
  const handleStartOptimization = async (values) => {
    setLoading(true);
    setOptimizing(true);
    setProgress(0);
    setResults(null); // Reset results when starting a new optimization
    
    // Process date range
    let dateRange = null;
    if (values.dateRange && values.dateRange.length === 2) {
      dateRange = {
        startDate: values.dateRange[0].format('YYYY-MM-DD'),
        endDate: values.dateRange[1].format('YYYY-MM-DD')
      };
    }
    
    try {
      // Simulate progress updates
      const progressInterval = setInterval(() => {
        setProgress(prev => {
          const newProgress = prev + Math.random() * 5;
          return newProgress >= 100 ? 100 : newProgress;
        });
      }, 500);
      
      // Call optimization API
      const optimizationParams = {
        codes: values.codes,
        paramRanges: values.paramRanges,
        optimizationTarget: values.optimizationTarget,
        iterationCount: values.iterationCount,
        dateRange,
        cycle: values.cycle // Add cycle parameter
      };
      
      console.log('Optimization parameters:', optimizationParams);
      const data = await optimizationApi.runOptimization(optimizationParams);
      
      // Clear progress interval and set results
      clearInterval(progressInterval);
      setProgress(100);
      
      // Validate the response structure
      if (data && data.results && Array.isArray(data.results)) {
        setResults(data);
      } else {
        console.error('Invalid optimization results structure:', data);
        message.error('获取优化结果失败：无效的数据结构');
      }
      
      // Delay ending optimization state to show 100% progress
      setTimeout(() => {
        setOptimizing(false);
      }, 500);
      
    } catch (error) {
      console.error('Error during optimization:', error);
      message.error('参数优化失败: ' + (error.response?.data?.detail || error.message));
    } finally {
      setLoading(false);
    }
  };
  
  // Save optimization result
  const handleSaveResult = async (result) => {
    try {
      await optimizationApi.saveOptimizationResult(result);
      message.success('参数已成功保存！可以在策略页面应用此参数。');
    } catch (error) {
      console.error('Error saving result:', error);
      message.error('保存参数失败: ' + (error.response?.data?.detail || error.message));
    }
  };
  
  return (
    <div className="optimization-page">
      <Row gutter={[24, 24]}>
        <Col xs={24} lg={24}>
          <Card title={
            <Space>
              <ExperimentOutlined />
              <span>参数优化</span>
            </Space>
          } bordered={false}>
            <Form
              form={form}
              layout="vertical"
              onFinish={handleStartOptimization}
            >
              <Row gutter={24}>
                <Col xs={24} md={12}>
                  <Form.Item
                    label="股票代码"
                    name="codes"
                    rules={[{ required: true, message: '请选择至少一个股票代码' }]}
                  >
                    <StockCodeSelector
                      selectedCodes={selectedCodes}
                      availableCodes={availableCodes}
                      onAddCode={handleAddCode}
                      onRemoveCode={handleRemoveCode}
                      onSelectGroup={handleSelectGroup}
                    />
                  </Form.Item>
                  
                  <Form.Item
                    label="日期范围（可选）"
                    name="dateRange"
                  >
                    <RangePicker 
                      style={{ width: '100%' }}
                      format="YYYY-MM-DD"
                    />
                  </Form.Item>
                  
                  <Form.Item
                    label="周期选择"
                    name="cycle"
                    rules={[{ required: true, message: '请选择回测周期' }]}
                  >
                    <Select>
                      {AVAILABLE_CYCLES.map(cycle => (
                        <Option key={cycle.value} value={cycle.value}>{cycle.label}</Option>
                      ))}
                    </Select>
                  </Form.Item>
                  
                  <Form.Item
                    label="优化目标"
                    name="optimizationTarget"
                    rules={[{ required: true, message: '请选择优化目标' }]}
                  >
                    <Select>
                      <Option value="finalReturn">最终收益</Option>
                      <Option value="annualizedReturn">年化收益</Option>
                      <Option value="sharpeRatio">夏普比率</Option>
                      <Option value="maxDrawdown">最小最大回撤</Option>
                      <Option value="winRate">胜率</Option>
                    </Select>
                  </Form.Item>
                  
                  <Form.Item
                    label="迭代次数"
                    name="iterationCount"
                    rules={[{ required: true, message: '请输入迭代次数' }]}
                  >
                    <InputNumber min={10} max={1000} style={{ width: '100%' }} />
                  </Form.Item>
                </Col>
                
                <Col xs={24} md={12}>
                  <Form.Item label="参数范围设置" name="paramRanges">
                    <ParamRangesConfig form={form} />
                  </Form.Item>
                </Col>
              </Row>
              
              <Form.Item>
                <Button 
                  type="primary" 
                  htmlType="submit" 
                  loading={loading}
                  icon={<ExperimentOutlined />}
                  block
                  disabled={optimizing}
                >
                  开始参数优化
                </Button>
              </Form.Item>
            </Form>
            
            {optimizing && (
              <div className="optimization-progress">
                <Alert
                  message="参数优化中..."
                  description="系统正在尝试不同的参数组合，以找到最优的策略参数。请耐心等待。"
                  type="info"
                  showIcon
                />
                <Progress percent={Math.round(progress)} status="active" />
              </div>
            )}
          </Card>
        </Col>
        
        <Col xs={24} lg={24}>
          {results && (
            <ResultsTable 
              results={results} 
              optimizationTarget={form.getFieldValue('optimizationTarget')}
              onSaveResult={handleSaveResult}
            />
          )}
        </Col>
      </Row>
    </div>
  );
};

export default Optimization; 